#include "simodo/lsp-client/SimodoCommandResult.h"

#include "simodo/inout/convert/functions.h"

namespace simodo::lsp
{
    namespace
    {
        bool parseSimodoCommandReport(const variable::Value & report_value, SimodoCommandReport & report)
        {
            if (report_value.type() != variable::ValueType::Object) 
                return false;

            std::shared_ptr<variable::Object> report_object = report_value.getObject();

            const variable::Value & id_value    = report_object->find(u"id");
            const variable::Value & title_value = report_object->find(u"title");
            const variable::Value & type_value  = report_object->find(u"type");
            const variable::Value & text_value  = report_object->find(u"text");

            if (id_value.type() == variable::ValueType::String)
                report.id = id_value.getString();
            if (title_value.type() == variable::ValueType::String)
                report.title = title_value.getString();
            if (type_value.type() == variable::ValueType::Int)
                report.type = static_cast<SimodoCommandReportType>(type_value.getInt());
            if (text_value.type() == variable::ValueType::String)
                report.text = inout::decodeSpecialChars(text_value.getString());

            return true;
        }
    }

    std::vector<SimodoCommandReport> parseSimodoCommandResult(const variable::Value & result_value)
    {
        std::vector<SimodoCommandReport> res;

        if (result_value.type() == variable::ValueType::Object) {
            SimodoCommandReport report;
            if (parseSimodoCommandReport(result_value, report))
                res.push_back(report);
            return res;
        }

        if (result_value.type() != variable::ValueType::Array)
            return res;

        std::shared_ptr<variable::Array> result_array = result_value.getArray();

        for(const variable::Value & report_value : result_array->values()) {
            SimodoCommandReport report;
            if (parseSimodoCommandReport(report_value, report))
                res.push_back(report);
        }

        return res;
    }

    bool parseSimodoCommandResult(const simodo::variable::Value & result_value, SimodoCommandResult & result)
    {
        if (result_value.type() != variable::ValueType::Object) 
            return false;

        std::shared_ptr<variable::Object> result_object = result_value.getObject();

        const variable::Value & uri_value           = result_object->find(u"uri");
        const variable::Value & commandResult_value = result_object->find(u"commandResult");

        if (uri_value.type() == variable::ValueType::String)
            result.uri = uri_value.getString();

        result.commandResult = parseSimodoCommandResult(commandResult_value);

        return true;
    }
}
